CToolsª
A collection of C source file utilities.

An itty bitty bytesª production.

Version 2.2.1d

©Copyright 1995 by Kenneth A. Long,

CToolsª was originally written by Graham Haddock.


Current Status

CToolsª was turned over to me by the author, Graham Haddock, who
has no time for further development or support.  

Address any bug reports, wish lists, suggestions, recommendations,
etc., to me, at:

kenlong@netcom.com


CToolsª Functions:
------------------
The CToolsª program is a collection of C text file tools and
utilities that are useful for formatting and reading C source
files, particularly some of the "stuff" that you obtain from
downloaded sources.  These tools and utilities have been wrapped
inside a Macintoshª shell that includes a rudimentary editor
function.  The editor is not intended for major programming
activities, but it is useful for viewing and making preliminary
modifications to files.


¥ C Source Formatter 
--------------------
A  "C" Source Formatter or "Pretty Printer" which operates on
files.  This utility will operate on any file which ends in the
suffix ".c".  It will re-indent a file according to the nesting
level of the segments of the program.  Multiple statements per
line will be reformatted to have one statement per line.  The
logic flow of a program (as viewed by a C compiler) should not be
disturbed, but you will generally find the program much easier to
read if it was not originally indented according to nesting
levels.

It adds an extra carriage, return after brace level returns to
zero, so that it will clean up a preprocessed file better.


¥ C Flow 
--------
Abstracts C function calls and declarations from a C source file
and produces a listing of the program's calling hierarchy.  This
utility will operate on any file which ends in the suffix ".c". 
It will generate a new  file with the original file name plus the
suffix ".flw" which contains a  sequential indented list of all
functions called from each function declaration.

It is a useful utility for understanding the overall flow and
calling structure of a program, particularly one that has
insufficient or no documentation or commenting.


 ¥ C Check
----------
A program to find and report all badly matched openers and closers
plus assignment/equality confusions in a C source file.  This
utility will operate on any file which ends in the suffix ".c". 
It will generate a new file with the original file name plus the
suffix ".check" which contains the output comments from the
utility.  It specifically comments on unbalanced openings and
closings of brackets, braces, etc., and specifically looks for the
use of "=" rather than "==" inside decision statements.  If the
"Verbose" option is selected, the utility will comment on the
placement of opening and closing braces which are not vertically
aligned in the source code.


¥ Cross Reference 
-----------------
This is a concordance or cross-reference utility for 'C' programs.
 This utility will operate on any file which ends in the suffix
".c".  It will generate a new file with the original file name
plus the suffix ".xref" which contains the cross referenced output
from the utility.  It will generate a list of all variable and
function names in the source code, along with the line number in
which they appear.  In accordance with the operation of Think Cª,
this program does not recognise nested comments, but  it will
properly deal with comments or quoted items which are inside
single or double quotes.

Options support the following features:
   - Cross-referencing of Think Cª reserved words.
   - Generation of line numbered listing only.
   - Generation of cross-reference only.


¥ Strip File 
------------
This tool is useful for cleaning up and converting files that you
have imported from other sources such as IBM-PC based files, or
Unix systems.

Text files obtained from IBM-PC based sources as viewed on a
Macintosh usually have a row of "boxes" down the left edge of the
screen, and a horizontal row of boxes at the bottom of the file. 
These are actually control characters which are present in the
file, but are not used by the Macintosh.  To convert and clean up
this kind of file, just click "OK" at the Stripper dialog, which
will remove all control characters not used by a Macintoshª text
file, as well as any characters with values above (hex)7F.

If the file does not appear to have any carriage returns, and the
file just goes on to the right forever, then the file is probably
a Unix type file, and the additional "Convert Unix File" option
should also be checked.  Unix type text files use "LineFeed" ($0A)
rather than "CarriageReturn" ($0D) as the Mac does to mark a new
line.  The "Convert Unix File" option will substitute a
CarriageReturn for each LineFeed before stripping.  If you check
this box on an IBM-PC type file, then you will end up with
everything double spaced, but no other harm done.

Although most Macintosh programs will not recognise them, there
are some text editors like QUED which will respond to imbedded
"Form Feeds" for page break control.  If these exist in the
program, and you want to save them, activate the "Save FormFeed"
option.


¥ Pascal to C 
-------------
This utility will translate Pascal keywords and operators to their
C equivalent.  This utility will operate on any files which DO NOT
end in the suffix ".c".  It will generate a new file with the
original file name plus the suffix ".p.c" which contains the
translated output from the utility.

This program is an aid in translating a Pascal program to C.  It
will do much of the repetitive mechanical conversion.  HOWEVER,
the programmer will need a working knowledge of both Pascal and C
to manually convert some Pascal features which this program cannot
handle, or for which there is no direct C equivalent.


¥ Prototype Generator 
---------------------
This utility will generate C type prototypes from an (old style) C
source file.   This tool has not been reworked to recognise ANSI
style declarations yet.   This utility will operate on any file
which ends in the suffix ".c".  It will generate a new file with
the original file name plus the suffix ".pr" which contains the
list of prototypes output by the utility.

(This one is almost useless.  How many old-style declarations do
you write or run into?  I recommend the SUPERIOR prototype
generator in CMasterª from Jersey Scientific.)


¥ Remove Tabs 
-------------
 This tool will convert all tabs to their equivalent number of
spaces, according to the number of spaces selected in the "Tabs"
menu.  The file may then be saved in this form, or it may then be
re-Tabbed to a different tab setting, without disturbing the
appearance of the file, by using the Re-Tab command below.  The
program will also absorb any trailing tabs or spaces at the end of
a line. 

As an example, if you have a Unixª style file with Tabs st 8
spaces that you wish to convert to 4 spaces, "Open" the file, and
then select a setting in the "Tabs" menu that appears to provide
the original appearance for the file.  Then run "De-Tab" to
convert all tabs to spaces.  Now select 4 spaces per tab in the
"Tabs" menu, and run "Re-Tab".  The appearance of any tables or
comment headers will now be preserved, while you are now free to
run the "C Source Formatter" on the source code.


¥ ReTab 
-------
This tool will convert any spaces (which are not inside " or '
quotes) into tabs according to the number of spaces per tab
selected in the "Tabs" menu.  Spaces inside " or ' quotes are
preserved.  The program will also absorb any trailing tabs or
spaces at the end of a line.  It is not necessary to run "De-Tab"
first, if you just want to clean up a file with the same Tab
setting, where spaces and tabs were used interchangeably.

New In
CToolsª version 2.2d:
---------------------
¥ Added this help module (but it's slightly buggy).
¥ Added Pascal to C comment style preferences.
¥ Pascal to C now creates #define for *plain* constants! (ItÕs a
start.)
¥ Pascal to C now handles *plain* 'for' statements!  (ItÕs a
start.)
¥ Pascal to C typedef and record conversion improved!
¥ Dropped formatter adding of spaces before certain left
parenthesis.


Improvements Since
CToolsª version 2.16:
---------------------
The jump from 2.16 to 2.2 was all on unreleased versions.  I
decided to start with the next highest, relatively even, version
number, for this release.

Pascal to C improvements:
¥ Fixed it to handle many, many more character case discrepancies
than before, on commonly encountered keywords.
¥ Added translate table entries to add left and right parens after
many common toolbox calls having no arguments.
(i.e. InitWindows; to InitWindows ();).
¥ Added translations for some minor, yet omitted, keywords and
other things. (see Appendix)
¥ Patched some small translation items resulting in less (or
easier to do) manual editing.
¥ Translate table additions: 135.
¥ Added conversion for PascalÕs Ô@Õ operator to CÕs Ô&Õ operator.

Other Improvements:
¥ Made CToolsª save ÔTEXTÕ files with its own signature, ÔGH22Õ
for quick spotting in the Finder and SFGet dialog.
¥ Gave CToolsª a new color icon.
¥ Added color animated cursor during long processes.
¥ Added "Select All" to the Edit Menu.
¥ Added command key modifiers to the CToolsª menu items.

To Do List:
- Make it handle ÔforÕ loops.
- Make it handle switches more completely.
- Make it do constants better.	Ã done (95%)
- Improve typedef and record conversion. 	Ã done
- Add Ô()Õ after argumentless routine calls.
- Make comment styles selectable.	Ã done
- Make source formatter configurable.
- Correct left off paren on do-while loop.
- Fix start brace dislocation in procedure parsing routine.
- Fix missing Ô;Õ on line before before ÔelseÕ.
- Put in more Ô&Õ where needed.
- Make Proto Gen work right for new and old style, so itÕs more
usable.

...eventually...
- Do C to Pascal.
- Do batch translating.
- Do flow of whole program
(That oughta keep me busy!)


Using CToolsª
-------------
The primary caution to be considered is memory.  CToolsª can
handle fairly big files, but has its limits.  If you do a big
operation, donÕt expect to b able to do another big operation
without saving.  For example, if yo do Pascal to C on a file, then
Source Code Formatter, it will crash.  If you do Pascal to C on
the same file (after you restart), then save, THEN do Source
Fomatter, it will probably not crash (didnÕt for me).  See?

------------------------------------------------------------------

C Source Formatter:
-------------------
The CToolsª C source formatter works beautifully.  It only works
on files suffixed in ".c" though.  

The C source formatter will operate on a "Command 1" key
combination on the open file, whereupon it does it and replaces
the ext in the file with the formatted text.  If you want to keep
this, then close and save, or vice versa.  Otherwise you MUST
select "Save As" from the file menu if you do not want your
original source altered.

I have never had an error in its output as long as the input was
compilable code and not too big.  Sometimes it will balk on a
BIGÊfile, or one with some unusual weirdnesses.  But thatÕs very
rare.  If it does do this, it will merely crash without eating
your file (hopefully).  What I do, when I KNOW I have too big a
file to format, is split it up.  Open the CToolsª "WorkSheet.c"
file, select half the file to be processed file, copy it, paste it
into the worksheet, format it, select all, cut, save the
worksheet, switch back to the intended file and paste and save. 
Then select the other half.  You can do this between your editor
and CToolsª or all in CToolsª.

The formatter doubles as a "C check" function, in that if there is
a missing brace or missing semicolon or missing paren, the Source
Formatter output will have odd indents immediately afterward.  You
can correct these glitches right in the CToolsª window.  Scroll
down until the code looks oddly indented, find the omission, add
it, and run the formatter again.

If you have a missing "case" keyword before a Ô:Õ then CToolsª
will not indent that line, so those are easy to find.

You can also paste a routine into a new CToolsª document being
used as a "worksheet" and format it, then cut or copy it out.  The
file must be "saved" with the ".c" suffix in order for it to work.
 But if you want to pump code and not deal with indents until you
are done, then just have CToolsª running in MultiFinder and, when
youÕre done typing, select all and copy, paste into your CToolsª
"worksheet.c", hit Command 1, select all and cut again, save the
worksheet.c file (save empty) and then paste your source back into
your code file.

One tip on big files, suppose you have a huge routine and CToolsª
doesnÕt have enough "poop" to process it?  Simply:

( 1) Move the insertion point to the top of the file in your code
editor.
( 2) Drag the scroll thimb halfway down.
( 3) Hold SHIFT and click near the left margin.
( 4) Command V.
( 5) Switch to the CToolsª Worksheet.c window.
( 6) Command 1.
( 7) Command A.
( 8) Command X.
( 9)Commad S.
(10) Switch back to your editor.
(11) Command V.  

Now, the tricky part...

YouÕll want the remaining, unformatted source from the file to
have the same indent as the part it goes under IF you are
mid-routine.  If you format the remainder the way it is, missing
begin braces will result in mismatched indents.  So, do this:

( 1) Put the insertion point just before the first character of
the last 
        line of the code you just formatted.
( 2) Hit the left arrow and count how many times you hit it to get
the
        insertion point to the left margin.
( 3) Hit the down arrow to get below that code.
( 4) Drag the scroll thumb to the bottom of the file.
( 5) Hold Shift and click past the end of all the code.
( 6) Command C.
( 7) Switch back to the CToolsª Worksheet.c window.
( 8) Type the same number of begin braces as the number of left
arrow hits 
        you counted earlier.
( 9) Command V.
(10) Command 1.
(11) Command X.
(12) Command S.
(13) Switch back to your editor.
(14) Command V.

I will be working in more user configurability but, until then,
YOU have to do a little configuration on your own if you do not
want your source to appear as CToolsª puts it out - but not much.

If a brace is on the same line as an 'if' statement it will stay
there.  If you want it on its own, new line, pre-edit by using a
Find/Replace function in a text editor.  Find " {" (space
leftBrace) and Replace All with "<cr>{" (return leftBrace) before
running the formatter.  A Find/Replace function will be added to
CToolsª, soon, so you can do this "in-house", but it will probably
just be a part of the preferences.

If you want to see how good this formatter is, preprocess a small
source file, replace all RETURNs with a space, save the result and
run the formatter on it!  

If you intend to clean up CToolsª output from the Pascal to C
function, you MUST edit it so that it has ALL matching braces,
parens and semicolons first.  The technique for doing this is
detailed in the Pascal to C section.

------------------------------------------------------------------

Pascal to C:
------------
Using the CToolsª Pascal to C function will save you a LOT of
work!  The sequence for doing so with CToolsª has five basic
steps:

(1) Get a complete rough C translation.
(2) Get all routines to appear in a "function popup" menu.
	(Good C source editors have function popups).
(3) Get the file ready to clean up with the CToolsª C Source
Formatter.
(4) Get it to compile and link.
(5) Get it to run.

Getting A Complete Translation

Sometimes CToolsª does not completely translate a file with the
CToolsª Pascal to C function.  Errors in getting a complete output
can be worked around.  If you run Pascal to C, scroll down the
output window to the bottom.  If there are no translation errors
you will see "}." there.  If not, there was an abnormal
termination of the translation due to something CToolsª is not yet
made able to handle.

Abnormal terminations are caused by:
(1) More than 32 variables being assigned to one type declaration.
	Solution:  Split them up.
(2) An array declared with a byte range (i.e. "0..255"), including
the
        "packed" Pascal keyword.
	Solution:  Change it before translating.
(3) Any wrong Pascal source, such as seen in a "Rascal" file, such
as void procedures which have parens, or some such.
	Solution:  Correct them.
(4) It seems to balk at the word "Implementation".
	Solution: Comment it out.

If an abnormal termination has happened, simply:

(1 ) Note WHERE in the Pascal file the translation stopped.
(2 ) CLOSE AND DO NOT SAVE the translation.
(3 ) Scroll down the open, original Pascal window to that place.
(4 ) Comment out or otherwise correct the erring line.
(5 ) Attempt another complete translation.
(6a) If complete, save and close the translation.
(6b) If incomplete, repeat steps 2 through 6.
(7 ) Close and do not save the original Pascal file.

Another form of incomplete translation, where it does not
abnormally terminate, yet does not properly translate, are when
the word "packed" is read in a type definition.

So, before you even try to translate the file, to save time and
trouble, it would be wise to pre-edit the Pascal file (a copy) and
remove all occurrences of the word "packed" and change any range
variables to the Pascal version of what they will end up being
(i.e. change "0..255" to "integer").

Multiple files:
---------------
The best way to do a primary, rough translation on a multiple file
program is to launch CToolsª and navigate, in the SFGetFile
dialog, to the desired Pascal source file set folder, scroll to
the bottom of the list, select the last file in the list and use
my "KodeKeys" macro.  The macro is a sequence which opens the
file, does Pascal to C and saves and closes the file, then looks
for another one.

From then on, itÕs just scroll, select, hit the hot-keys.  When
you get done with the top one on the list, click Cancel.

Manually, once you navigate and select the bottom one on the list,
translate it (making sure itÕs complete), save, close, close,
open, select the second to the last one, etc., etc., until youÕve
rough translated them ALL.

The reason you start at the bottom of the list should be obvious. 
If not, itÕs because when you add translated files to the list *it
grows*.  If you start at the top, clicks in the pageDown will
become more numerous to get to the ones not yet done.  Start at
the bottom and the navigation to the undone ones will be minimal.

Merge Them
----------
If you are translating a complete Pascal program, consisting of
multiple source and unit files, it is far better to edit ALL the
files at once.  Chances are what produces a compiler error in one
file will produce them in others.  ItÕs better to correct an error
throughout the entire source/header area, than to set up
"Find/Replace" several times, one file at a time

To do this, get a complete CToolsª output for ALL the files. 
Units and .p files.  Pascal programs sometimes have a "Globals.p"
file (with whatever actual name).  CToolsª will save it as
"Globals.p.c" but it will eventually end up being the main header
file, "Globals.h."  What you need to do is MERGE all files
(kilobyte size permitting) and put all global data files at the
top.  You can separate them back into .c files later, but for the
purposes of manual editing, it is essential to have the least
number of files (preferably one) as possible.

My Think C has been allocated with enough memory to easily handle
a 300K merged file.  Set yours up to the maximum possible - within
reason.

What I do is run all the files through CToolsª Pascal to C, then
select all the output files destined to become headers and drop
them on TextMerge by Robert Gibson.  This creates a new file
called "Merged File 0" and consists of copies of the content of
all the files in alpha. order (View by Name).  I do the same with
what will become sources and itÕs named "Merged File 1".  Then I
drop both these on the merger and it outputs "Merged File 2" which
I rename to Merged.c.

Your alphabetical order is changed by adding an ÔaÕ prefix to some
file names and a ÔzÕ to others, prior to the merge.  Once merged,
the Merged File 3 is renamed "Merge.c" (or the program name) for
editing.  Dump the first merges, retaining only the rough
translation files (put all their names back like they were) and
Merge.c.

One advantage is you now have copies of your CToolsª output, in
case you want to revert to, or refer to, any of it in editing the
merged file.  But the main advantage is you only have to correct
one thing ONCE instead of for each file.  And you do the
correction for the whole program the FIRSTÊtime it is encountered.

Navigation from file to file without excessive scrolling is a snap
with CMasterª (or your "Command E" and then Command G without
CMasterª) by selecting the word "translation" and using the
up/down search arrows.  ThatÕs a unique word in the merged file
and appears at the top of EACH individual file which was merged.


A little Pleasure Before the Pain...
------------------------------------
At this point, once you get a completed file translation, whether
single or multiple files, you may as well set up a project for the
soon to be running C program.  Launch your environment, create a
new project with the proper name, add all the libraries it will
need, add all the CToolsª ouput files you just created, do what
you need in order to get the resource file associated with the
project.

DonÕt be concerned, at this point, about the xxxx.p.c suffix on
the file names, or the ÔGH22Õ creator of them.  A later step will
make those right.  Set the project preferences to be all "kosher"
(clean, in order, right) for the new program.

If you will be editing with your environments editor, then you
will likely not need to open any of the converted files youÕve
added.  YouÕll be concentrating on on getting the surrogate
"Merged.c" to compile.


Let the Pain Begin!
-------------------
It's time for manual editing!  Get the Preparation H restocked,
put on the wrist straps, load up several coffee filters in
advance, etc!  Here we go!

YouÕll do the editing in your favorite code editor. I have
developed several ways of making the manual editing go faster and
easier.

Once you have translated the file, quit CToolsª and open the new
.p.c file in your code editor.  Two things that will help here ,
tremendously, is Think C with CMasterª and QuicKeysª (as
mentioned).  Without these two things (or comparable utilities, if
that's possible) the editing of CToolsª Pascal to C output can and
will be a drudgery.  But, still, not as bad as a direct
translation of a Pascal file (although IÕve got that down to a
science, too)!

In addition to these two EXCELLENT utilities, adding in a
"Command-equivalent" key for your "Replace All" menu item is
essential!  I use the asterisk, because itÕs right next to the
mouse, on the numeric keypad.  You do NOT want to be making a
mouse trip to the menu bar for the Replace All function!  You are
going to be using it 100s of times in the coming task!

Use ResEdit or Commander, or whatever, but get a unique
Command/equivalent modifier key for this menu item. (Make sure you
use a unique key.)


Function Pop-Up:
----------------
The first goal in editing is to get all the routines to show up in
the "Function Pop-Up" menu.  This is so you will know youÕve got
whole routines to End Of File, and also for faster navigation.  If
you donÕt do this first, they will just be extra compiler errors
later.

For all routines to so appear in the popup, there must be an equal
number of start and end braces, and no "nested functions."

CToolsª only converts the "var" and first "begin" in place.  It
eats "var" and changes "begin" into a begining brace.  Since
Pascal is "backward", these begining braces are in the wrong place
- after the variables.  This is relatively easy to remedy.

Find:

)<CR>   // (right paren, return)

and replace with:

)<CR>{  // (right paren, return, left brace)

Do this manually using Command G and/or Command H, so you can SEE
what you are changing.  Automatic ("Replace All") will create the
need for extra editing by doing it to ALL routines!  You donÕt
want to do it to routines - only prototypes.

Before dealing with the, now, extra brace, you MUST replace the:

};

with:

}

You can use the Replace All command for this one.  This is done to
prevent interference with the next two editing steps without
eating your start braces on nested functions.

Still cleaning up the extra start braces, youÕll find two
situations:
(1) The extra begin brace is after a line ending in a comment.
(2) The extra begin brace is after a line ending in Ô;Õ.

In either case, there may be one or more carriage returns, then
one or more TABs, before the brace.  If thereÕs one RETURN and one
TAB, Find:

;
    {    // (semicolon, return, tab, left brace)

and replace with:

;
       // (semicolon, return)

You may have to add TABs and RETURNs as needed, depending on the
variety of indents and returns carried over from the Pascal.

On this last one, the only thing that will prevent you from
getting them all is a comment after the ';' in the first line.  To
find these, use the Function Pop Up.  The extra brace will be in
the bottom one on the list or in the routine just below it.


Nested Routines
---------------
The only remaining preventer of all routines showing up in the
popup are Pascals lovely "nested functions" thingy.  These are
fairly easy to fix.  Sometimes they can be quite complex.

In the Function Pop Up, one of these will be the bottom routine on
the list.  They are identified by a start brace but then a
complete routine after the variables are declared.  HereÕs an
example from "Icosahedron":

In the Pascal to C output, itÕs:

// The primary routine beginning.
void Shadefaces()
{                        // You have to add this brace.
    short ThisFace;      // These variables...
    RgnHandle aRegion;   // ...do not appear...
    short Level;         // ...in the nested routine.

    // Nested routine begins here.
    double Bright (Coordinates PlaneNorm, Coordinates LightNorm)
    {
        Bright = ((PlaneNorm[1] * LightNorm[1] +
                   PlaneNorm[2] * LightNorm[2] + 
                   PlaneNorm[3] * LightNorm[3]) + 1.0) / 2.0
    }    // End of nested routine.

{    // Begin of primary routine.
    aRegion = NewRgn();  // First used from primary variables.
    for (ThisFace = 0; ThisFace < kNumFaces; ThisFace++)
    {
	[snip]
		level = ceil(Bright(Normal, light) * 64.0);
	[snip]
    }
}    //¥ Shadefaces.    // End of primary routine.

Select the part above the complete routine and copy it.  In
CMasterª, hit your hot-keys (or tool icon) to comment this out.

// void Shadefaces()
// {
//     short ThisFace;      // These variables...
//     RgnHandle aRegion;   // ...do not appear...
//     short Level;         // ...in the nested routine.

Now, scroll down until you find the actual start of that copied
routine declaration with variables.  There'll be a start brace
right after an end brace.  Depending on how many functions are
nested within it, the first one of these you find may or may not
be where that goes.  Sometimes the author of the Pascal code marks
it with a comment (hopefully).  Anyway, wherever you find it,
select the start brace, hit RETURN and then paste the declaration
and variables.

In our example, hereÕs what you end up with:

// UN-Nested routine begins here.
double Bright (Coordinates PlaneNorm, Coordinates LightNorm)
{
    Bright = ((PlaneNorm[1] * LightNorm[1] +
               PlaneNorm[2] * LightNorm[2] + 
               PlaneNorm[3] * LightNorm[3]) + 1.0) / 2.0
}    // End of nested routine.

(NOTE: The array element values are all 1 too high.)

// The primary routine beginning.
void Shadefaces()
{                        // You have to add this brace.
    short ThisFace;      // These...
    RgnHandle aRegion;   // ...do not appear...
    short Level;         // ...in the nested routine.
                         // Where original "begin" was.
    aRegion = NewRgn();  // First used from primary variables.
    for (ThisFace = 0; ThisFace < kNumFaces; ThisFace++)
    {
	[snip]
		level = ceil(Bright(Normal, light) * 64.0);
	[snip]
    }
}    //¥ Shadefaces.    // End of primary routine.

One way you can find them is to look in the variables in the
"primary header declaration" (which you copied and commented out)
and find the first occurrence of its use, following it.  There
will often be one that is unique to the body of the routine where
that declaration goes.  In the example, Bright did not contain
ThisFace, aRegion or Level, so you can find the "nest" with those
as search strings.  The next occurrence of one of these variables
beyond its original location, where thereÕs a Ô}Õ followed by a
Ô{Ô just above it, will be where the primary function beginning
goes.

If there are several nested routines, the first set of variables
may belong to more than one of them.  You donÕt need to be
concerned about those until compile time.  A decision will have to
be made whether to make several locals or all of those global, at
that time.

Now check the Function Pop Up.
------------------------------
So, you just repeat these steps until ALL routines show in the
popup.  The last routine - main () - will not be declared.  YouÕll
have to type in the declaration yourself.  Pascal programmers
usually mark this well.

The last brace of the program file (end of "main") has a dot after
it which you may as well remove while youÕre there.


Cleaning It Up:
---------------
Now that youÕve got the routines "popping up all over the place",
you must handle any other things which will prevent CToolsª C
Source Formatter from giving a clean output, which is the next
goal of editing.  The reason you do this now is because it takes
care of a few things which would become compiler errors, and it
makes the C source (itÕs not Pascal any more) easier to read and
follow.

These preventers are:

(1) Last right paren (')') missing from the end of a do-while
loop.
(2) Improper or absent switch components (i.e. no "case " or
"break;").
(3) No end-of-line semicolon (;) before "else" keywords.

For the "do-while" in CMasterª, you simply find "while" and using
the up/down selection search function to find them.  Start at the
top of the file, click the down button, if it is a "while" at the
end of a do/while loop, hit Command leftArrow, then rightArrow
once and type a ')' there.  If there are comments on the line, you
must manually place the insertion point.  Do this until EOF or it
wraps back to the first one.  If you donÕt have CMasterª use
Command G and the left/right arrows as above.

Improper switch components are no "case " before the cases, no
"break;" between the cases commas where ":RETURNcase " should go. 
If you have KodeKeys, you've been "saved" from a monotonous,
drudgery.  Use my KodeKeys macro set for these (does one
intermediate comma).

Use Find to find the first occurrence of the word "switch" in your
CToolsª output.  In CMasterª, get that word into the selection
search queue.  You can see that the word "case " is missing from
the switch components.  Put them there.

With my macros, you simply put the insertion point before the
first one and type "ctrl[3]" (control key, numeric pad 3).

Move down to where the next "case " goes, type "break;", hit
RETURN twice and type "case " again.

With my KodeKeys macros, simply put the insertion point where
"case " goes and type "ctrl-option-[3]" (control, option, numeric
pad 3).  It's automagically and correctly updated.

If there are two case possibilities, with a comma, like:

keyDown, autoKey:

then hit "ctrl-shift-[3]" using the KodeKeys macros.  It will turn
the above into:

break;

case keyDown:
case autoKey:

in one shot!

Otherwise, just type in "case " and a space and replace the comma
with a ':' and return and another "case" and space, so that it
looks like the above example.

When you get down to the last one, you type "break" after it.  The
macro for that is "ctrl[2]" alone.

It may be that break; does not belong there.  Maybe it has return,
instead.  Determine this as you go.

Lastly, find all else with CMasterÕs selection/search function and
add a Ô;Õ to the end of the previous code line (where they are
missing).

Now, if you are in a big merged file, format the source later -
after a complete compile and youÕve split the files back up into
their individual .c files.  On a single file, run the CToolsª C
Source Formatter now, to sort out the appearance.  This editing
step will not make the source proper for the compiler, but will
make it easier and ready to edit for compilation.

Be sure not to feed the formatter too big a chuck of code to
format at one time.


Compiling
---------
Now that youÕve got all routines sorted out to pop up in the menu,
and have all Ô;Õ and  Ô)Õ and Ô{Ô and switches taken care of, itÕs
time to get it to compile in C.  

In Think C, I use "Check Syntax" on the file, rather than "Run" or
"Compile."  That way I donÕt have to deal with the error window. 
No need to try to compile or run when you KNOW it wonÕt do either,
at this point!  The error window will only give you the first
error anyway.

CToolsª only marks some things which the user may or may not want
done a certain way.  The first of these is "Includes:" - the
carry-over from Pascals "Uses" line.

My KodeKeys macros can help, here.  Hit ctrl-i for #include <.h>
or ctrl-option-i for #include ".h", then just paste in the name of
the header included.

Add the appropriate include directives and comment out or cut out
the "dead" code.  Pascal includes (uses) some of its own source
files.  C does not usually do this.  So, in the ".p" file, which
once may have said "Uses MyMenus.p", it does not, now, need
"#include "MyMenus.p.c".  Dig?  C only wants header data.  If
there is "header stock" in the "MyMenus.p.c" file that IS needed
by another c. file, then cut it and put it in a seperate header.

For the rest of the file, you may want to consult the Pascal
original for comparisons - especially if an omission is suspected.
 Also, compare forms of whatÕs translated to comparable things in
working C sources.  From that, a good "source detective" should be
able to get a correct translation where CToolsª falls down.


Constants:
----------
CToolsª now does constants fairly well!.  Yaaaay!  About 95% of
them will require no further editing IF you want #defines.  The
remaing 5% will be fixed.  Until then, you have to clean these up
manually.  What I do is copy them all out to a new file where I
can use Find/Replace without messing up something else, fix them
all up fast and copy/paste them back.

HereÕs an example of output which balked:

Pascal input:
HOMEKEY = chr(1);

CToolsª output:
#define HOMEKEY chr#define 1/***# Expected const identifier ***/

Correction:

Replace All "/***# Expected const identifier ***/" with a space
and Find
all the second "#define " using Command G/H and replace with a
space, to get:

#define HOMEKEY chr 1	

See...  I only just got it to do constants into defines.  I need
to add something to handle parens and such.

If the constant has more than a definition and a meaning, such as a
plus or anything more than the two words (or #s), it will go out of
synchronization.  The output can still be editied but not as easily
as if the were merely commented out ahead of time.
On a multi-file, use CToolsª "#define" keyword to navigate down
the file, to get to where these incorrectly translated contants
are.


Typedefs:
---------
Most typedefs will be usable, if youÕve pre-edited the range types
and removed the "packed" keword.   If the Pascal range in an array
was from zero, the translated one may be one short.  It used to
automatically add "+1" to all of them.  I removed that as kludge,
because the majority are translated correctly.  So watch for
discrepancies.

Compare the "translation" to a working C source, and compare to
the Pascal original, to make them complete and correct.  Or look
at some typedefs in you Mac #includes headers, to see how they
should be.


From Then, On:
--------------
Once past the typedefs, the global variables will be mostly ready
to go exactly as they are.  And the rest of the file will be
relatively easy to edit.

If CToolsª hits a "Str4[4] name;" it will scramble it with a 
previous type.  Just look at the Pascal file and see how itÕs 
supposed to be and fix it.  just find these ahead of thime and
chanege them to Str255 or whatever.  (This is just another thing 
on my list of things to correct - will  it ever end!).

The biggest "pest" of the editing process is screwed up character
case.  It may say "itemHit" 20 times in the file, and one or two
times it will say "ItemHit" or "itemhit" or even "ITEMHIT".  My
KodeKeys macros handle this.  And, whenever you encounter ANYTHING
that gives a compiler error, correct it for the rest of the file
right then and there.

One important thing is, when you use Find/Replace, be SURE you
evaluate whether to set "Ignore Case", "Wrap Around" and "Whole
Words" FIRST.  The "Selection - Replace All" KodeKeys sequence I
just mentioned MUST have "Whole Words" checked before using it. 
Otherwise it will mess up some things.

Using Find/Replace for C source from a Pascal conversion is an
art, to selectively edit the whole file precisely.

Sometimes you will fix something in the rest of the file and it
will mess up something you already edited.  ShouldÕve had "Wrap
Around" unchecked!  See?

The oddball character case boo-foos usually show up with the "xxxx
has not been declared" compiler error, but you KNOW it has already
been declared (the ONE exception to this is in a "with" block). 
So, it was declared and used earlier, but with one or more
characters in the wrong case.  I can correct this so itÕs
automatically handled.  Until then...  (ho hum)...

The quickest way to handle this is to get the one where you are
like you want all of them to be, select it, copy it, and paste it
in the Find dialog for both the search string and the replace-with
string, and then Replace All (Whole Words checked).  Editing this
one word for character case is made easy by having a macro in
CMasterª to invert case.  I do this with one key hit of the "back
accent" key (upper left of keyboard).  IÕve never used that
character for anything else, so I use it for that.  I hit it and
the next character gets inverted, case-wise.  Or on a selection
and the entire selectio inverts case.  EXCELLENT!  Handy!

For those of you using KodeKeys, simply edit the word to your
liking (donÕt add or subtract characters), select it, then hit
ctrl-[0] (control, keypad 0) and the sequence will be executed. 
ItÕs mega-fast and easy!  (Make sure "Whole Words" is checked
before doing this.)


"VAR" Left in Parameters
------------------------
Sorry about this one, too (I didnÕt write  the thing!).  These are
handled easily, for the whole file, by setting up Find with "var "
(var, space) and Replace With with nothing  and hitting Command G
to find them individually.  When you find one leave it there, add
the Ô*Õ before the variable name it goes to and hit Command G
again.  Do this from the top, until it wraps, and then Replace All
by hitting your Command *.  Any other way is slower and more
invloved.


"WITH" Blocks
-------------
The *exception* to the undeclared variable name which you know has
already been declared is in the "with" block and is easy to spot. 
You get a compiler error saying "so-and-so has not been declared".
 You suspect screwy character case.  With KodeKeys, you edit the
offender and select it and hit "ctrl[0]" and all occurrences of it
are changed to the upper/lower you just set.  Attempt a compile
and still get the same error.  Look just above that for a "with"
marker.  HereÕs an example:

	//¥ WITH:  oldRect )	// CToolsª marker.
	{
		SizeWindow(wPtr, right - left, bottom - top, false);
		ResizeText(good)		/* redraw text in wind**/
	;}

The error was "right" has not been declared.  Well, you KNOW it
has been, in QuickDraw.h!  So the "with" is the culprit.  With
what?  Something goes WITH "right". "oldRect" goes with it!  So,
you put a dot after "oldRect", hold down SHIFT, click in front of
"oldRect." and copy to the clip.  Put the cursor in front of
"right" and paste.  Continue this for any other "undeclared" in
the "with" block (in this case identified by braces) and move on
to the next error.  The finished product will look like this:

    //¥ WITH:  oldRect. )// CToolsª marker.
    {
        SizeWindow(wPtr, oldRect.right  - oldRect.left, 
                         oldRect.bottom - oldRect.top, false);
        ResizeText(good);	/* redraw text in wind**/
    }

The braces delineating the "with" block should be left in, for the
time being.  Sometimes there are nested or double WITH blocks, and
these braces help reduce confusion.  Leave the  with marker in,
also.  You may have to come back and get information or do
something else.  Save removing this stuff until the final posh up,
after it runs.

Nested WITHs are handled similarly.  They will say:

//¥ with something, somethingElse )

or

//¥ with oneThing )
{
	SomeStuff (one, two, three);
	//¥ with anotherThing )
	{
		SomeMoreStuff (four, five, six);
		[on and on]
	}
	[blah, blah, blah]
}

It may be tricky figuring out what goes WITH what.  I recommend
getting a copy of Icosahedron.p and Icosahedron.c and comparing
them, if you run into a severe nested with block.  It has a LOT of
them and both programs run.

A hint as to what goes with what is in the type of variable the
names belong to, and what struct they are in.  The ones with
rectangle references for one "with" are fairly easy to figure out.


Missing ParenthesisÕ
--------------------
CToolsª does not (yet) add the parens for non-toolbox functions
which have no arguments.  I know.  I hate that, too.  But I have
macros for both " ()" and "();"  and they are easy to find and
add.

The fastest way to do these is let them all go as long as the
compiler does not complain.  Then, once you get to the end of the
file without syntax errors, use the CMasterª prototype generator
to generate prototypes for the whole file and place them just
before the first routine.  Then, scroll down the prototype list
and find any void of arguments, select the routine name, use the
CMasterª selection search arrow to find each occurrence of it. 
When you find one, simply hit the right arrow and then hit
ctrl-[1] or ctrl-option[1] as needed.  With "wrap" set on the
selection search, it will come back to the prototype and youÕll
know you got them all.  Then just do the next one down the list.

CToolsª also does not fix the parenthesis around casts.  If the
line says:

DoSomethingWith (char(doHickey));

Then you Find "(char(" and Replace All with "((char)(" and remove
the other parenÕs around "(doHickey)" later, unless donÕt you
*love* editing code!  They wonÕt hurt anything if left in.

The few remaining "gotchas" are regular C - plus toolbox -
compiler errors.  


Missing Ampersands
------------------
Like "(FindWindow (), whichWindow);" having no ampersand (&)
before "whichWindow".  That one will cause a crash - not just a
debugger error, when you get past compile and link.

Speaking of ampersands... Toolbox calls requiring the "address of"
operator (ampersand, or Ô&Õ), like SetRect and lots of other
QuickDraw calls, are best handled (as IÕve said) for the whole
file when the first one is encountered.  CToolsª only takes care
of converting the Ô@Õ which was already in the Pascal program. 
Almost ALL Pascal IÕve seen has no spaces before the first paren
of a call.  This is to your advantage in the translation process. 
Suppose youÕre doing "SetRect" missing ampersands...

You want "Whole Words" checked so you donÕt mess up "OffsetRect". 
But you also want "Ignore Case" checked in case there are
instances or "setrect" or "SETrect" or some such.  Fix all that
can be fixed with each correction you do.

Find "SetRect(" and replace with "SetRect (&".  See?  We added a
space before the paren.  Why?  Well, if you do Replace All, it
wonÕt matter.  But if you replace one at a time (Replace, Find
Again) you have to be careful not to go past where you started,
thus creating more editing to handle the over correction.  It will
find "SetRect(&" and fix it with "SetRect(&&".  See?  With the
space after the paren it wonÕt redo one already done.

So I always add the space between the call and its paren,
especially when using Command G/H.  Besides, itÕs proper
punctuation in English!

(The "CopyBits" and "CopyMask" will drive you crazy if you
translate Stella Obscura by John Calhoun!  CopyBits needs 4
ampersands.  As I recall, there were 90 CopyBits calls in Stella
Obscura - probably 45 CopyMask calls!  I can probably set up some
built in macros to handle some of these.)

In my KodeKeys macros, I use the single Ô.Õ key on the numeric
keypad section of the keyboard to type an ampersand.  That way I
donÕt have to use the shift key.  One hand on the mouse and one
finger on the other hand on that key and I can knock these things
in like nobodyÕs business.


Array Elements
--------------
Since Pascal counts from Ô1Õ and C counts from Ô0Õ youÕll have to
manually adjust array element designations.

In Pascal:

    procedure Normalize (var ThePoint: Coordinates);
        var
            Length: Real;
    begin
        Length := SQRT(ThePoint[1] * ThePoint[1] + 
                       ThePoint[2] * ThePoint[2] + 
                       ThePoint[3] * ThePoint[3]);

        ThePoint[1] := ThePoint[1] / Length;
        ThePoint[2] := ThePoint[2] / Length;
        ThePoint[3] := ThePoint[3] / Length
    end;

shows the array "ThePoint" to have 3 elements.  ItÕs still 3 in C 
but are designated 0, 1 and 2 instead of 1, 2 and 3.  So the above
would become:

void Normalize (Coordinates *ThePoint);
{
    double Length;

    Length = sqrt(ThePoint[0] * ThePoint[0] + 
                  ThePoint[1] * ThePoint[2] + 
                  ThePoint[2] * ThePoint[2]);
                  ThePoint[0] = ThePoint[0] / Length;
                  ThePoint[1] = ThePoint[1] / Length;
                  ThePoint[2] = ThePoint[2] / Length
}

All array element designations reduced by one.  There ARE some
that donÕt get changed.  YouÕll have to play it by ear to see
which is which.  The key is in the declaration.  If it says
"typedef short widget [3]" then you know that "widget[1]" is one
too high.  This is probably why the original author added the "+1"
the the array bounds parser - so this would still work (?). 

While weÕre on arrays, CToolsª doesnÕt bracket two dimensional
ones right.  If the Pascal says "widgets [1, 20]" then  will, too.
 So you have to replace the ", " with "][" between them, to make
"widgets[1][20]".  The compiler will find these for you.  If you
have a lot of them, you may be able to Find all "[1, " and replace
with "[1][" to do it faster.


Linking
-------
If you get a complete compile, chances are youÕll get some link
errors.  Usually, again, these will be because of screwed up
character case.  Some managed to sneak through.

With your C conversion is in one file, just Select All in the Link
Error window, copy and close it.  Then paste this stuff at the
bottom of the converted program file.  Now you can use my
Selection/Replace All macro to fix any of these stragglers (or use
your editors Find/Replace).  Then cut the errors back off the EOF
and try to get a run.  ALWAYS use debugger in the first run
attempts of a conversion!  It may run fine.  It may not.  If it
does not, the debugger MAY be a cushion against a crash or freeze.

I usually set a breakpoint after the first call in "main" and see
if it gets that far.  Then I "leapfrog" the rest of the way, in
the same way, finally tracking down any crashes, bugs, bus errors,
odd addresses - the usual.


Re-Splitting files:
-------------------
This is easy.  Hopefully, you have all the rough translated,
separate, unedited files added to your project file already, with
appropriate libraries added, and ready to "run."

With the Merge.c file open, get to the top of the file.  Once
there, read the file name that the first section goes to (if the
Pascal programmer didnÕt put it there CToolsª did).  Remember that
fileName so you know where it goes.

Now, using the word "translation" as the search string, find the
next occurrence of that word.  It will be at the start of the
second file block of Merge.c.

Put the insertion point at the start of the line that
"translation" appears in, by clicking there.

Now, without clicking in the viewRect, use the vertical scroll
thumb and scroll back to the top of the file.

Hold down the shift key and click just before the start of any
text,  Hit Command C to cut that file off the top of the Merge.c 
file.  Be sure to Save the Merge.C file to manage memory as needed.

Now, open the file that cut source goes to and Select All and
paste.  You now have a brand new, shiny, C source file, in your
newly ported version of the Pascal project!  BEFORE you save the
file, use *Save As* from the File menu and remove the ".p" from
the file name.  This will make the name added to the project be
what itÕs supposed to be and save the new file in the creator of
YOUR editor, rather than that of CToolsª, as I mentioned earlier.

Continue these steps until the Merge.C file is empty.

At this point, run the CToolsª Source Code Formatter on each of
these files, if needed.


Done Deal!
----------
Pat yourself on the back - but not to the point of getting
callouses!  YouÕve just accomplished a major feat!  YouÕre a
"cunning linguist - you spoke Pascal AND C!"  But this may be
premature exhilaration - you still have to get the thing to run
right.  ThatÕs not part of the job of CToolsª.  ThatÕs YOUR job. 
But the worst is over and you are unscathed and minus a few pots
of coffee (and maybe a box of Preparation H?).  Well done!


Extra Help
----------
The best "text" on Pascal to C is a set of sources for the same
program in both languages and compared.  Aside from that, any
comparison of parts of a program (like a CopyBits call, for
example) is good.  AÊrecent c.s.m.p. article on Pascal to C
reprinted from MacTech magazine was *excellent*!

Hope
----
CToolsª will eventually be working a LOT better than it is.  It
already works a lot better than it once did.  CToolsª is basically
a text manipulating function set.  It doesnÕt "know" Pascal OR C. 
As a "character pusher" it works pretty good.  But it doesnÕt work
good enough to suit me.  Probably has a few "things to be desired"
for you, too.  Let me know what they are!

Considering a good Pascal to C converter can cost up to $7,500
(Sierra Software InnovationsÕ "p2c" MPW tool), CToolsª is a hell
of a deal!

Any questions?

Enjoy!

kenlong@netcom.com

Appendix

(Some of these are cosmetic.  Most are for character case.  Some
are for translation purposes.)

Color code: CToolsª 2.16, CToolsª 2.2

"and",	"&&"
"autokey",	"autoKey"
"backcolor",	"BackColor"
"begin",	"{"
"beginupdate",	"BeginUpdate"
"bitand",	""
"bitmap",	"BitMap"
"bittst",	""
"boolean",	"boolean"
"boolean",	"Boolean"
"bottom",	"bottom"
"bsl",	"//¥ <<"
"bsr",	"//¥ >>"
"button",	"Button ()"
"byte",	"char"
"case",	"switch"
"case",	"switch ("
"cgrafptr",	"CGrafPtr"
"char",	"char"
"charcodemask",	"charCodeMask"
"chr",	"char"
"closepoly",	"ClosePoly ()"
"closergn",	"CloseRgn "
"cmdkey",	"cmdKey"
"concat",	"strcat"
"const",	"/* CONST */\r#define "
"const",	"//¥ Constants:\r"
"controlhandle",	"ControlHandle"
"copy",	"strcpy"
"cos",	"cos"
"curresfile",	"CurResFile ()"
"dialogptr",	"DialogPtr"
"diskevt",	"diskEvt"
"div",	"/"
"do",	")"
"downto",	";/*DOWNTO*/"
"downto",	"; ¥ >="
"drawmenubar",	"DrawMenuBar ()"
"else",	"; else"
"else",	"else"
"end",	"}"
"endupdate",	"EndUpdate"
"everyevent",	"everyEvent"
"extended",	"float"
"false",	"FALSE"
"false",	"false"
"fixed",	"Fixed"
"fontinfo",	"FontInfo"
"for",	"for ("
"forecolor",	"ForeColor"
"frontwindow",	"FrontWindow ()"
"getctseed",	"GetCTSeed ()"
"getdevicelist",	"GetDeviceList ()"
"getgdevice",	"GetGDevice ()"
"getmaindevice",	"GetMainDevice ()"
"getport",	"GetPort"
"grafptr",	"GrafPtr"
"handle",	"Handle"
"hidecursor",	"HideCursor ()"
"hidepen",	"HidePen ()"
"hlock",	"HLock"
"hunlock",	"HUnlock"
"if",	"if ("
"implementation",	"/* private (static) section */"
"implementation",	""
"incontent",	"inContent"
"indesk",	"inDesk"
"indrag",	"inDrag"
"ingoaway",	"inGoAway"
"ingrow",	"inGrow"
"initcursor",	"InitCursor ()"
"initdialogs",	"InitDialogs"
"initfonts",	"InitFonts ()"
"initgraf",	"InitGraf"
"initmenus",	"InitMenus ()"
"initwindows",	"InitWindows ()"
"inline",	"\tasm\r\t{\r\t"
"inmenubar",	"inMenuBar"
"input",	"stdin"
"insetrect",	"InsetRect"
"insyswindow",	"inSysWindow"
"integer",	"int"
"integer",	"short"
"interface",	"/* exported symbol section */"
"interface",	"//¥ Proto's:"
"invertroundrect","InvertRoundRect"
"inzoomin",	"inZoomIn"
"inzoomout",	"inZoomOut"
"ioresult",	"errno"
"itemhit",	"itemHit"
"keydown",	"keyDown"
"left",	"left"
"length",	"strlen"
"line",	"Line"
"lineto",	"LineTo"
"longint",	"long"
"maxapplzone",	"MaxApplZone ()"
"memerror",	"MemError ()"
"mod",	"%"
"moremasters",	"MoreMasters ()"
"mousedown",	"mouseDown"
"moveto",	"MoveTo"
"newPixpat",	"NewPixPat ()"
"newpixmap",	"NewPixMap ()"
"newrgn",	"NewRgn ()"
"nil",	"NULL"
"not",	"!"
"null",	"NULL"
"obscurecursor"	,"ObscureCursor ()"
"of",	"{"
"of",	")\r\t\t\t{"
"offsetrect",	"OffsetRect"
"openpoly",	"OpenPoly ()"
"openrgn",	"OpenRgn ()"
"or",	"||"
"oserr",	"OSErr"
"otherwise",	"default"
"output",	"stdout"
"packed",	"/* PACKED */"
"packed",	"//¥ packed"
"pattern",	"Pattern"
"pennormal",	"PenNormal ()"
"pichandle",	"PicHandle"
"point",	"Point"
"pointer",	"Ptr"
"portbits",	"portBits"
"portrect",	"portRect"
"procedure",	"void"
"program",	"main"
"program",	"//¥ main"
"ptinrect",	"PtInRect"
"ptr",	"Ptr"
"qderror",	"QDError ()"
"random",	"Random ()"
"read",	"scanf"
"readln",	"/*LINE*/scanf"
"readln",	"//¥ scanf"
"real",	"double"
"record",	""
"rect",	"Rect"
"repeat",	"do {"
"repeat",	"do\r\t\t{"
"reserror",	"ResError ()"
"rgbcolor",	"RGBColor"
"rgnhandle",	"RgnHandle"
"right",	"right"
"round",	"ceil"
"screenbits",	"screenBits"
"setport",	"SetPort"
"setrect",	"SetRect"
"showcursor",	"ShowCursor ()"
"showpen",	"ShowPen ()"
"showwindow",	"ShowWindow"
"sin",	"sin"
"size",	"Size"
"sizeof",	"sizeof"
"sqrt",	"sqrt"
"srcxor",	"srcXor"
"str255",	"Str255"
"sysbeep",	"SysBeep"
"sysenvrec",	"SysEnvRec"
"systemtask",	"SystemTask ()"
"teinit",	"TEInit ()"
"the",	"the"
"then",	")"
"theport",	"qd.thePort"
"tickcount",	"TickCount ()"
"to",	";"
"to",	"; ¥ <"
"top",	"top"
"true",	"TRUE"
"true",	"true"
"trunc",	"floor"
"type",	"\r/* typedefs */\r"
"type",	"//¥ typedefs:"
"udateevt",	"updateEvt"
"unit",	"//¥"
"unloadscrap",	"UnloadScrap ()"
"until",	"} until ("
"until",	"} while (! "
"updateevt",	"updateEvt"
"uses",	"\r/* USES */\r#include"
"uses",	"//¥ includes:"
"var",	"\r/* VAR */\r"
"var",	""
"whichwindow",	"whichWindow"
"while",	"while ("
"windowptr",	"WindowPtr"
"with",	"/* WITH */"
"with",	"//¥ WITH: "
"write",	"printf"
"writeln",	"/*LINE*/printf"
"writeln",	"//¥ printf"
"zeroscrap",	"ZeroScrap ()"
